home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Online / x3270 / unix_files / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  2009-01-02  |  15.9 KB  |  619 lines

  1. /*
  2.  * Modifications Copyright 1993, 1994, 1995, 1996, 1999, 2000 by Paul Mattes.
  3.  * Original X11 Port Copyright 1990 by Jeff Sparkes.
  4.  *  Permission to use, copy, modify, and distribute this software and its
  5.  *  documentation for any purpose and without fee is hereby granted,
  6.  *  provided that the above copyright notice appear in all copies and that
  7.  *  both that copyright notice and this permission notice appear in
  8.  *  supporting documentation.
  9.  *
  10.  * Copyright 1989 by Georgia Tech Research Corporation, Atlanta, GA 30332.
  11.  *  All Rights Reserved.  GTRC hereby grants public use of this software.
  12.  *  Derivative works based on this software must incorporate this copyright
  13.  *  notice.
  14.  */
  15.  
  16. /*
  17.  *    main.c
  18.  *        A 3270 Terminal Emulator for X11
  19.  *        Main proceudre.
  20.  */
  21.  
  22. #include "globals.h"
  23. #include <sys/wait.h>
  24. #include <X11/StringDefs.h>
  25. #include <X11/Core.h>
  26. #include <X11/Shell.h>
  27. #include <X11/Xatom.h>
  28. #include <signal.h>
  29. #include "appres.h"
  30. #include "3270ds.h"
  31. #include "resources.h"
  32.  
  33. #include "actionsc.h"
  34. #include "ansic.h"
  35. #include "charsetc.h"
  36. #include "ctlrc.h"
  37. #include "ftc.h"
  38. #include "hostc.h"
  39. #include "keymapc.h"
  40. #include "kybdc.h"
  41. #include "macrosc.h"
  42. #include "menubarc.h"
  43. #include "popupsc.h"
  44. #include "resourcesc.h"
  45. #include "savec.h"
  46. #include "screenc.h"
  47. #include "selectc.h"
  48. #include "statusc.h"
  49. #include "telnetc.h"
  50. #include "togglesc.h"
  51. #include "trace_dsc.h"
  52. #include "utilc.h"
  53.  
  54. /* Externals */
  55. #if defined(USE_APP_DEFAULTS) /*[*/
  56. extern const char *app_defaults_version;
  57. #else /*][*/
  58. extern String    color_fallbacks[];
  59. extern String    mono_fallbacks[];
  60. #endif /*]*/
  61.  
  62. /* Globals */
  63. char           *programname;
  64. Display        *display;
  65. int             default_screen;
  66. Window          root_window;
  67. int             screen_depth;
  68. Widget          toplevel;
  69. XtAppContext    appcontext;
  70. Atom            a_delete_me, a_save_yourself, a_3270, a_registry, a_iso8859,
  71.         a_ISO8859, a_encoding, a_1, a_state;
  72. char        full_model_name[13] = "IBM-";
  73. char           *model_name = &full_model_name[4];
  74. Pixmap          gray;
  75. XrmDatabase     rdb;
  76. AppRes          appres;
  77. int        children = 0;
  78. Boolean        exiting = False;
  79.  
  80. /* Statics */
  81. static void    peek_at_xevent(XEvent *);
  82. static XtErrorMsgHandler old_emh;
  83. static void    trap_colormaps(String, String, String, String, String *,
  84.             Cardinal *);
  85. static Boolean  colormap_failure = False;
  86. #if defined(LOCAL_PROCESS) /*[*/
  87. static void    parse_local_process(int *argcp, char **argv, char **cmds);
  88. #endif /*]*/
  89. static void    parse_set_clear(int *, char **);
  90. static void    label_init(void);
  91. static char    *user_title = CN;
  92. static char    *user_icon_name = CN;
  93.  
  94. XrmOptionDescRec options[]= {
  95.     { OptActiveIcon,DotActiveIcon,    XrmoptionNoArg,        ResTrue },
  96.     { OptAplMode,    DotAplMode,    XrmoptionNoArg,        ResTrue },
  97.     { OptCharClass,    DotCharClass,    XrmoptionSepArg,    NULL },
  98.     { OptCharset,    DotCharset,    XrmoptionSepArg,    NULL },
  99.     { OptClear,    ".xxx",        XrmoptionSkipArg,    NULL },
  100.     { OptColorScheme,DotColorScheme,XrmoptionSepArg,    NULL },
  101.     { OptDsTrace,    DotDsTrace,    XrmoptionNoArg,        ResTrue },
  102.     { OptEmulatorFont,DotEmulatorFont,XrmoptionSepArg,    NULL },
  103.     { OptExtended,    DotExtended,    XrmoptionNoArg,        ResTrue },
  104.     { OptIconName,    ".iconName",    XrmoptionSepArg,    NULL },
  105.     { OptIconX,    ".iconX",    XrmoptionSepArg,    NULL },
  106.     { OptIconY,    ".iconY",    XrmoptionSepArg,    NULL },
  107.     { OptKeymap,    DotKeymap,    XrmoptionSepArg,    NULL },
  108.     { OptKeypadOn,    DotKeypadOn,    XrmoptionNoArg,        ResTrue },
  109.     { OptM3279,    DotM3279,    XrmoptionNoArg,        ResTrue },
  110.     { OptModel,    DotModel,    XrmoptionSepArg,    NULL },
  111.     { OptMono,    DotMono,    XrmoptionNoArg,        ResTrue },
  112.     { OptNoScrollBar,DotScrollBar,    XrmoptionNoArg,        ResFalse },
  113.     { OptOnce,    DotOnce,    XrmoptionNoArg,        ResTrue },
  114.     { OptOversize,    DotOversize,    XrmoptionSepArg,    NULL },
  115.     { OptPort,    DotPort,    XrmoptionSepArg,    NULL },
  116.     { OptReconnect,    DotReconnect,    XrmoptionNoArg,        ResTrue },
  117.     { OptSaveLines,    DotSaveLines,    XrmoptionSepArg,    NULL },
  118.     { OptScripted,    DotScripted,    XrmoptionNoArg,        ResTrue },
  119.     { OptScrollBar,    DotScrollBar,    XrmoptionNoArg,        ResTrue },
  120.     { OptSet,    ".xxx",        XrmoptionSkipArg,    NULL },
  121.     { OptTermName,    DotTermName,    XrmoptionSepArg,    NULL },
  122.     { OptTraceFile,    DotTraceFile,    XrmoptionSepArg,    NULL }
  123. };
  124. int num_options = XtNumber(options);
  125.  
  126. /* Fallback resources. */
  127. #if defined(USE_APP_DEFAULTS) /*[*/
  128. static String fallbacks[] = {
  129.     "*adVersion:    fallback",
  130.     NULL
  131. };
  132. #else /*][*/
  133. static String *fallbacks = color_fallbacks;
  134. #endif /*]*/
  135.  
  136. struct toggle_name toggle_names[N_TOGGLES] = {
  137.     { ResMonoCase,        MONOCASE },
  138.     { ResAltCursor,       ALT_CURSOR },
  139.     { ResCursorBlink,     CURSOR_BLINK },
  140.     { ResShowTiming,      SHOW_TIMING },
  141.     { ResCursorPos,       CURSOR_POS },
  142. #if defined(X3270_TRACE) /*[*/
  143.     { ResDsTrace,         DS_TRACE },
  144. #endif /*]*/
  145.     { ResScrollBar,       SCROLL_BAR },
  146. #if defined(X3270_ANSI) /*[*/
  147.     { ResLineWrap,        LINE_WRAP },
  148. #endif /*]*/
  149.     { ResBlankFill,       BLANK_FILL },
  150. #if defined(X3270_TRACE) /*[*/
  151.     { ResScreenTrace,     SCREEN_TRACE },
  152.     { ResEventTrace,      EVENT_TRACE },
  153. #endif /*]*/
  154.     { ResMarginedPaste,   MARGINED_PASTE },
  155.     { ResRectangleSelect, RECTANGLE_SELECT }
  156. };
  157.  
  158.  
  159. static void
  160. usage(const char *msg)
  161. {
  162.     if (msg != CN)
  163.         XtWarning(msg);
  164. #if defined(X3270_MENUS) /*[*/
  165.     xs_error("Usage: %s [options] [[ps:][LUname@]hostname[:port]]", programname);
  166. #else /*][*/
  167.     xs_error("Usage: %s [options] [ps:][LUname@]hostname[:port]", programname);
  168. #endif /*]*/
  169. }
  170.  
  171. static void
  172. no_minus(char *arg)
  173. {
  174.     if (arg[0] == '-')
  175.         usage(xs_buffer("Unknown or incomplete option: %s", arg));
  176. }
  177.  
  178. int
  179. main(int argc, char *argv[])
  180. {
  181. #if !defined(USE_APP_DEFAULTS) /*[*/
  182.     char    *dname;
  183.     int    i;
  184. #endif /*]*/
  185.     Atom    protocols[2];
  186.     char    *cl_hostname = CN;
  187.     int    ovc, ovr;
  188.     char    junk;
  189.     int    sl;
  190.  
  191.     /* Figure out who we are */
  192.     programname = strrchr(argv[0], '/');
  193.     if (programname)
  194.         ++programname;
  195.     else
  196.         programname = argv[0];
  197.  
  198.     /* Save a copy of the command-line args for merging later. */
  199.     save_args(argc, argv);
  200.  
  201. #if !defined(USE_APP_DEFAULTS) /*[*/
  202.     /*
  203.      * Figure out which fallbacks to use, based on the "-mono"
  204.      * switch on the command line, and the depth of the display.
  205.      */
  206.     dname = CN;
  207.     for (i = 1; i < argc; i++) {
  208.         if (!strcmp(argv[i], "-mono"))
  209.             fallbacks = mono_fallbacks;
  210.         else if (!strcmp(argv[i], "-display") && argc > i)
  211.             dname = argv[i+1];
  212.     }
  213.     display = XOpenDisplay(dname);
  214.     if (display == (Display *)NULL)
  215.         XtError("Can't open display");
  216.     if (DefaultDepthOfScreen(XDefaultScreenOfDisplay(display)) == 1)
  217.         fallbacks = mono_fallbacks;
  218.     XCloseDisplay(display);
  219. #endif /*]*/
  220.  
  221.     /* Initialize. */
  222.     toplevel = XtVaAppInitialize(
  223.         &appcontext,
  224. #if defined(USE_APP_DEFAULTS) /*[*/
  225.         "X3270",
  226. #else /*][*/
  227.         "X3270xad",    /* explicitly _not_ X3270 */
  228. #endif /*]*/
  229.         options, num_options,
  230.         &argc, argv,
  231.         fallbacks,
  232.         XtNinput, True,
  233.         XtNallowShellResize, False,
  234.         NULL);
  235.     display = XtDisplay(toplevel);
  236.     rdb = XtDatabase(display);
  237.  
  238.     /* Merge in the profile. */
  239.     merge_profile(&rdb);
  240.  
  241.     old_emh = XtAppSetWarningMsgHandler(appcontext,
  242.         (XtErrorMsgHandler)trap_colormaps);
  243.     XtGetApplicationResources(toplevel, (XtPointer)&appres, resources,
  244.         num_resources, 0, 0);
  245.     (void) XtAppSetWarningMsgHandler(appcontext, old_emh);
  246.  
  247. #if defined(USE_APP_DEFAULTS) /*[*/
  248.     /* Check the app-defaults version. */
  249.     if (!appres.ad_version)
  250.         XtError("Outdated app-defaults file");
  251.     else if (!strcmp(appres.ad_version, "fallback"))
  252.         XtError("No app-defaults file");
  253.     else if (strcmp(appres.ad_version, app_defaults_version))
  254.         xs_error("app-defaults version mismatch: want %s, got %s",
  255.             app_defaults_version, appres.ad_version);
  256. #endif /*]*/
  257.  
  258. #if defined(LOCAL_PROCESS) /*[*/
  259.     /* Pick out the -e option. */
  260.     parse_local_process(&argc, argv, &cl_hostname);
  261. #endif /*]*/
  262.  
  263.     /* Pick out -set and -clear toggle options. */
  264.     parse_set_clear(&argc, argv);
  265.  
  266.     /* Verify command-line syntax. */
  267.     switch (argc) {
  268.         case 1:
  269. #if !defined(X3270_MENUS) /*[*/
  270.         if (cl_hostname == CN)
  271.             usage(CN);
  272. #endif /*]*/
  273.         break;
  274.         case 2:
  275.         if (cl_hostname != CN)
  276.             usage(CN);
  277.         no_minus(argv[1]);
  278.         cl_hostname = argv[1];
  279.         break;
  280.         case 3:
  281.         if (cl_hostname != CN)
  282.             usage(CN);
  283.         no_minus(argv[1]);
  284.         no_minus(argv[2]);
  285.         cl_hostname = xs_buffer("%s:%s", argv[1], argv[2]);
  286.         break;
  287.         default:
  288.         usage(CN);
  289.         break;
  290.     }
  291.  
  292.     default_screen = DefaultScreen(display);
  293.     root_window = RootWindow(display, default_screen);
  294.     screen_depth = DefaultDepthOfScreen(XtScreen(toplevel));
  295.  
  296.     /* Sort out model, color and extended data stream modes. */
  297.     appres.model = XtNewString(appres.model);
  298.     if (!strncmp(appres.model, "3278", 4)) {
  299.         appres.m3279 = False;
  300.         appres.model = appres.model + 4;
  301.         if (appres.model[0] == '-')
  302.             ++appres.model;
  303.     } else if (!strncmp(appres.model, "3279", 4)) {
  304.         appres.m3279 = True;
  305.         appres.model = appres.model + 4;
  306.         if (appres.model[0] == '-')
  307.             ++appres.model;
  308.     }
  309.     sl = strlen(appres.model);
  310.     if (sl && (appres.model[sl-1] == 'E' || appres.model[sl-1] == 'e')) {
  311.         appres.extended = True;
  312.         appres.model[sl-1] = '\0';
  313.         sl--;
  314.         if (sl && appres.model[sl-1] == '-')
  315.             appres.model[sl-1] = '\0';
  316.     }
  317.     if (!appres.model[0])
  318. #if defined(RESTRICT_3279) /*[*/
  319.         appres.model = XtNewString("3");
  320. #else /*][*/
  321.         appres.model = XtNewString("4");
  322. #endif /*]*/
  323.     if (appres.m3279)
  324.         appres.extended = True;
  325.     if (screen_depth <= 1 || colormap_failure)
  326.         appres.mono = True;
  327.     if (appres.mono) {
  328.         appres.use_cursor_color = False;
  329.         appres.m3279 = False;
  330.     }
  331.     if (!appres.extended)
  332.         appres.oversize = CN;
  333.     if (appres.secure)
  334.         appres.disconnect_clear = True;
  335.  
  336.     a_delete_me = XInternAtom(display, "WM_DELETE_WINDOW", False);
  337.     a_save_yourself = XInternAtom(display, "WM_SAVE_YOURSELF", False);
  338.     a_3270 = XInternAtom(display, "3270", False);
  339.     a_registry = XInternAtom(display, "CHARSET_REGISTRY", False);
  340.     a_ISO8859 = XInternAtom(display, "ISO8859", False);
  341.     a_iso8859 = XInternAtom(display, "iso8859", False);
  342.     a_encoding = XInternAtom(display, "CHARSET_ENCODING", False);
  343.     a_1 = XInternAtom(display, "1", False);
  344.     a_state = XInternAtom(display, "WM_STATE", False);
  345.  
  346.     XtAppAddActions(appcontext, actions, actioncount);
  347.  
  348.     /* Initialize fonts. */
  349.     font_init();
  350.  
  351. #if defined(RESTRICT_3279) /*[*/
  352.     if (appres.m3279 && !strcmp(appres.model, "4"))
  353.         appres.model = "3";
  354. #endif /*]*/
  355.     if (!appres.extended || appres.oversize == CN ||
  356.         sscanf(appres.oversize, "%dx%d%c", &ovc, &ovr, &junk) != 2) {
  357.         ovc = 0;
  358.         ovr = 0;
  359.     }
  360.     set_rows_cols(atoi(appres.model), ovc, ovr);
  361.     if (appres.termname != CN)
  362.         termtype = appres.termname;
  363.     else
  364.         termtype = full_model_name;
  365.  
  366.     hostfile_init();
  367.  
  368.     keymap_init(appres.key_map);
  369.  
  370.     if (appres.apl_mode) {
  371.         appres.compose_map = XtNewString(Apl);
  372.         appres.charset = XtNewString(Apl);
  373.     }
  374.     if (!charset_init(appres.charset))
  375.         xs_warning("Cannot find charset \"%s\"", appres.charset);
  376.  
  377.     /* Initialize the icon. */
  378.     icon_init();
  379.  
  380.     /*
  381.      * If no hostname is specified on the command line, ignore certain
  382.      * options.
  383.      */
  384.     if (argc <= 1) {
  385. #if defined(LOCAL_PROCESS) /*[*/
  386.         if (cl_hostname == CN)
  387. #endif /*]*/
  388.             appres.once = False;
  389.         appres.reconnect = False;
  390.     }
  391.  
  392. #if !defined(X3270_MENUS) /*[*/
  393.     /*
  394.      * If there are no menus, then -once is the default; let -reconnect
  395.      * override it.
  396.      */
  397.     if (appres.reconnect)
  398.         appres.once = False;
  399. #endif /*]*/
  400.  
  401.     if (appres.char_class != CN)
  402.         reclass(appres.char_class);
  403.  
  404.     screen_init();
  405.     kybd_init();
  406.     ansi_init();
  407.     sms_init();
  408.     error_popup_init();
  409.     info_popup_init();
  410. #if defined(X3270_FT) && !defined(X3270_MENUS) /*[*/
  411.     ft_init();
  412. #endif /*]*/
  413.  
  414.     protocols[0] = a_delete_me;
  415.     protocols[1] = a_save_yourself;
  416.     XSetWMProtocols(display, XtWindow(toplevel), protocols, 2);
  417.  
  418.     /* Save the command line. */
  419.     save_init(argc, argv[1], argv[2]);
  420.  
  421.     /* Make sure we don't fall over any SIGPIPEs. */
  422.     (void) signal(SIGPIPE, SIG_IGN);
  423.  
  424.     /* Set up the window and icon labels. */
  425.     label_init();
  426.  
  427.     /* Handle initial toggle settings. */
  428. #if defined(X3270_TRACE) /*[*/
  429.     if (!appres.debug_tracing) {
  430.         appres.toggle[DS_TRACE].value = False;
  431.         appres.toggle[EVENT_TRACE].value = False;
  432.     }
  433. #endif /*]*/
  434.     initialize_toggles();
  435.  
  436.     /* Connect to the host. */
  437.     if (cl_hostname != CN)
  438.         (void) host_connect(cl_hostname);
  439.  
  440.     /* Prepare to run a peer script. */
  441.     peer_script_init();
  442.  
  443.     /* Process X events forever. */
  444.     while (1) {
  445.         XEvent        event;
  446.  
  447.         while (XtAppPending(appcontext) & (XtIMXEvent | XtIMTimer)) {
  448.             if (XtAppPeekEvent(appcontext, &event))
  449.                 peek_at_xevent(&event);
  450.             XtAppProcessEvent(appcontext,
  451.                 XtIMXEvent | XtIMTimer);
  452.         }
  453.         screen_disp();
  454.         XtAppProcessEvent(appcontext, XtIMAll);
  455.  
  456.         if (children && waitpid(0, (int *)0, WNOHANG) > 0)
  457.             --children;
  458.     }
  459. }
  460.  
  461. /* Change the window and icon labels. */
  462. static void
  463. relabel(Boolean ignored unused)
  464. {
  465.     char *title;
  466.     char icon_label[8];
  467.  
  468.     if (user_title != CN && user_icon_name != CN)
  469.         return;
  470.     title = XtMalloc(10 + ((PCONNECTED || appres.reconnect) ?
  471.                         strlen(reconnect_host) : 0));
  472.     if (PCONNECTED || appres.reconnect) {
  473.         (void) sprintf(title, "x3270-%d%s %s", model_num,
  474.             (IN_ANSI ? "A" : ""), reconnect_host);
  475.         if (user_title == CN)
  476.             XtVaSetValues(toplevel, XtNtitle, title, NULL);
  477.         if (user_icon_name == CN)
  478.             XtVaSetValues(toplevel,
  479.                 XtNiconName, reconnect_host,
  480.                 NULL);
  481.         set_aicon_label(reconnect_host);
  482.     } else {
  483.         (void) sprintf(title, "x3270-%d", model_num);
  484.         (void) sprintf(icon_label, "x3270-%d", model_num);
  485.         if (user_title == CN)
  486.             XtVaSetValues(toplevel, XtNtitle, title, NULL);
  487.         if (user_icon_name == CN)
  488.             XtVaSetValues(toplevel, XtNiconName, icon_label, NULL);
  489.         set_aicon_label(icon_label);
  490.     }
  491.     XtFree(title);
  492. }
  493.  
  494. /* Respect the user's label/icon wishes and set up the label/icon callbacks. */
  495. static void
  496. label_init(void)
  497. {
  498.     user_title = get_resource(XtNtitle);
  499.     user_icon_name = get_resource(XtNiconName);
  500.     if (user_icon_name != CN)
  501.         set_aicon_label(user_icon_name);
  502.  
  503.     register_schange(ST_HALF_CONNECT, relabel);
  504.     register_schange(ST_CONNECT, relabel);
  505.     register_schange(ST_3270_MODE, relabel);
  506.     register_schange(ST_REMODEL, relabel);
  507. }
  508.  
  509. /*
  510.  * Peek at X events before Xt does, calling PA_KeymapNotify_action if we see a
  511.  * KeymapEvent.  This is to get around an (apparent) server bug that causes
  512.  * Keymap events to come in with a window id of 0, so Xt never calls our
  513.  * event handler.
  514.  *
  515.  * If the bug is ever fixed, this code will be redundant but harmless.
  516.  */
  517. static void
  518. peek_at_xevent(XEvent *e)
  519. {
  520.     static Cardinal zero = 0;
  521.  
  522.     if (e->type == KeymapNotify) {
  523.         ia_cause = IA_PEEK;
  524.         PA_KeymapNotify_action((Widget)NULL, e, (String *)NULL, &zero);
  525.     }
  526. }
  527.  
  528.  
  529. /*
  530.  * Warning message trap, for catching colormap failures.
  531.  */
  532. static void
  533. trap_colormaps(String name, String type, String class, String defaultp,
  534.     String *params, Cardinal *num_params)
  535. {
  536.     if (!strcmp(type, "cvtStringToPixel"))
  537.         colormap_failure = True;
  538.     (*old_emh)(name, type, class, defaultp, params, num_params);
  539. }
  540.  
  541. #if defined(LOCAL_PROCESS) /*[*/
  542. /*
  543.  * Pick out the -e option.
  544.  */
  545. static void
  546. parse_local_process(int *argcp, char **argv, char **cmds)
  547. {
  548.     int i, j;
  549.     int e_len = -1;
  550.  
  551.     for (i = 1; i < *argcp; i++) {
  552.         if (strcmp(argv[i], OptLocalProcess))
  553.             continue;
  554.  
  555.         /* Matched.  Copy 'em. */
  556.         e_len = strlen(OptLocalProcess) + 1;
  557.         for (j = i+1; j < *argcp; j++) {
  558.             e_len += 1 + strlen(argv[j]);
  559.         }
  560.         e_len++;
  561.         *cmds = XtMalloc(e_len);
  562.         (void) strcpy(*cmds, OptLocalProcess);
  563.         for (j = i+1; j < *argcp; j++) {
  564.             (void) strcat(strcat(*cmds, " "), argv[j]);
  565.         }
  566.  
  567.         /* Stamp out the remaining args. */
  568.         *argcp = i;
  569.         argv[i] = CN;
  570.         break;
  571.     }
  572. }
  573. #endif /*]*/
  574.  
  575. /*
  576.  * Pick out -set and -clear toggle options.
  577.  */
  578. static void
  579. parse_set_clear(int *argcp, char **argv)
  580. {
  581.     int i, j;
  582.     int argc_out = 0;
  583.     char **argv_out = (char **) XtMalloc((*argcp + 1) * sizeof(char *));
  584.  
  585.     argv_out[argc_out++] = argv[0];
  586.  
  587.     for (i = 1; i < *argcp; i++) {
  588.         Boolean is_set = False;
  589.  
  590.         if (!strcmp(argv[i], OptSet))
  591.             is_set = True;
  592.         else if (strcmp(argv[i], OptClear)) {
  593.             argv_out[argc_out++] = argv[i];
  594.             continue;
  595.         }
  596.  
  597.         if (i == *argcp - 1)    /* missing arg */
  598.             continue;
  599.  
  600.         /* Delete the argument. */
  601.         i++;
  602.  
  603.         for (j = 0; j < N_TOGGLES; j++)
  604.             if (!strcmp(argv[i], toggle_names[j].name)) {
  605.                 appres.toggle[toggle_names[j].index].value =
  606.                     is_set;
  607.                 break;
  608.             }
  609.         if (j >= N_TOGGLES)
  610.             usage("Unknown toggle name");
  611.  
  612.     }
  613.     *argcp = argc_out;
  614.     argv_out[argc_out] = CN;
  615.     (void) memcpy((char *)argv, (char *)argv_out,
  616.         (argc_out + 1) * sizeof(char *));
  617.     XtFree((XtPointer)argv_out);
  618. }
  619.